package edu.uoc.tfc.web.tags;



import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.Tag;

import org.apache.commons.lang.StringUtils;



public abstract class AbstractFormFieldTag extends EmktBaseTag 
{



    private static final long serialVersionUID = 1L;

    private String label;
    private String name;
    private String value;
    private FormTag form;
	private String help;
	private boolean resolveHelp = true;
    private boolean editableOnlyOnCreation = false;
    private String linkedField;
    private boolean number = false;

	public boolean isNumber() {
		return number;
	}

	public void setNumber(boolean number) {
		this.number = number;
	}

	public String getLabel() {
    	return label;
    }

	public void setLabel(String label) {
    	this.label = label;
    }



    public String getName() {
    	return name;
    }

	public void setName(String name) {
    	this.name = name;
    }



	public String getValue() {
    	return value;
    }

	public void setValue(String value) {
    	this.value = value;
    }



	protected FormTag getForm() {
		return form;
	}

	protected void setForm(FormTag form) {
		this.form = form;
	}



	public String getHelp() {
    	return help;
    }

	public void setHelp(String help) {
    	this.help = help;
    }



	public boolean isResolveHelp() {
    	return resolveHelp;
    }

	public void setResolveHelp(boolean resolveHelp) {
    	this.resolveHelp = resolveHelp;
    }



	public boolean isEditableOnlyOnCreation() {
    	return editableOnlyOnCreation;
    }

	public void setEditableOnlyOnCreation(boolean editableOnlyOnCreation) {
    	this.editableOnlyOnCreation = editableOnlyOnCreation;
    }



    public String getLinkedField() {
    	return linkedField;
    }

	public void setLinkedField(String linkedField) {
    	this.linkedField = linkedField;
    }



	protected abstract void doStartFormField(JspWriter out) throws JspException;

	protected abstract void doEndFormField(JspWriter out) throws JspException;



	@Override
	public int doStartTag() throws JspException
	{
		try
		{
			initialize();

			JspWriter out = pageContext.getOut();

			write(out,"<div class=\"control-group\" id=\"" + getId() + "-control\">");

			writeLabel(out);

			write(out,"<div class=\"controls\">");

			doStartFormField(out);
		}
		catch (Exception ex)
		{
			String message = "Error generando Campo de formulario: " + ex.getMessage();
			throw new JspException(message);
		}

		return EVAL_BODY_INCLUDE;
	}



	@Override
    public int doEndTag() throws JspException
    {
		try
		{
			JspWriter out = pageContext.getOut();

			doEndFormField(out);

			write(out,"<span class=\"help-inline\" id=\"" + getId() + "-help\">");
			if (StringUtils.isNotBlank(getHelp()))
			{
				if (isResolveHelp())
				{
					write(out, getMessage(getHelp(), null));
				}
				else
				{
					write(out, getHelp());
				}
			}
			write(out,"</span>");

			if (StringUtils.isNotBlank(getLinkedField()))
			{
				write(out, "<script type=\"text/javascript\">");
				write(out, "  $(document).ready(function() {");
				write(out, "    prepareLinkedField(\"" + getId() + "\", \"" + getLinkedField() + "\", \"" + getValue() + "\")");
				write(out, "  });");
				write(out, "</script>");
			}

			write(out,"</div>");
			write(out,"</div>");
		}
		catch (Exception ex)
		{
			String message = "Error finalizando Campo de formulario: " + ex.getMessage();
			throw new JspException(message);
		}

	    return EVAL_PAGE;
    }



	protected void initialize()
	{
		Tag parentTag = this;
		boolean found = false;
		int counter = 0;
		do
		{
			parentTag = parentTag.getParent();
			found = parentTag instanceof FormTag;
		}
		while ((!found && counter++ < EmktBaseTag.MAX_DEEP && parentTag != null));

	    if (found)
	    {
	    	setForm((FormTag) parentTag);
	    }
	    else
	    {
	    	String message = "Error generando Campo de formulario por no estar incluido en un Formulario";
	    }

		setId(escapeNameForJqueryId(getName()));
    }



	protected void writeLabel(JspWriter out) throws Exception
	{
		if (StringUtils.isNotBlank(getLabel()))
		{
			write(out, "<label class=\"control-label\" for=\"" + getName() + "\">");
			write(out, getMessage(getLabel(), null));
			if (isRequired() && !form.isReadonly())
			{
				write(out, " *");
			}
			write(out, "</label>");
		}
    }



	protected boolean isWritable()
	{
		return !(
			isReadonly() ||
			getForm().getType() == FormType.Readonly ||
			(
				(
					getForm().getType() == null ||
					getForm().getType() == FormType.Modification
				) &&
				isEditableOnlyOnCreation()
			)
		);
	}



	protected String getClassMode()
	{
		StringBuilder classMode = new StringBuilder("input-xlarge");

    	if (this.isNumber()){
    		classMode.append(" numeric_input");
    	}
    	
		if (isWritable())
		{
			if (isRequired())
			{
				classMode.append(" emkt-required");
			}
			classMode.append(" focused");
		}
		else
		{
			classMode.append(" uneditable-input");
		}
		return classMode.toString();
	}



}
